import LoadingComponent from './index.vue'

let $vm
let watcher
let delayTime = null
let maxTimeOut = null

const mxLoading = {
  install (vue, options) {
    const Loading = vue.extend(LoadingComponent)

    if (!$vm) {
      $vm = new Loading({
        el: document.createElement('div')
      })
      document.body.appendChild($vm.$el)
    }

    const loading = {
      show (options = {}) {
        // destroy watcher
        watcher && watcher()
        if (typeof options === 'string') {
          $vm.text = options
        } else if (typeof options === 'object') {
          // Object.assign({}, $vm, options)
          Object.assign($vm, options)
        }
        if ((typeof options === 'object' && options.onShow) || options.onHide) {
          watcher = $vm.$watch('show', val => {
            val && options.onShow && options.onShow($vm)
            val === false && options.onHide && options.onHide($vm)
          })
        }
        delayTime && clearTimeout(delayTime)
        let delay = options.delay || 0
        delayTime = setTimeout(() => {
          $vm.appear = true
        }, options.delay || 0)

        maxTimeOut && clearTimeout(maxTimeOut)
        let timeout = options.maxTimeOut ? options.maxTimeOut + delay : 30000 + delay
        maxTimeOut = setTimeout(() => {
          clearTimeout(delayTime)
          $vm.appear = false
          delayTime = null
        }, timeout)
      },
      hide () {
        if (delayTime) {
          clearTimeout(delayTime)
          clearTimeout(maxTimeOut)
          delayTime = null
        }
        $vm.appear = false
      },
      isVisible () {
        return $vm.appear
      }
    }

    vue.$mxLoading = loading
    vue.mixin({
      created: function () {
        this.$mxLoading = vue.$mxLoading
      }
    })
  }
}

export default mxLoading
